package com.tedu.api.io;

import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import org.junit.Test;

import java.io.*;

/**
 *标准IO流---目的：数据传输  输出文本,图片
 * Java定义一套标准流-->数据传输-->创建流：直接创建某个流对象
 * 标准流规则：①方向划分：输入流、输出流
 *            输入流：读入-->文件-->相对于程序-->文件往程序走
 *            InputStream(抽象类：定义所有读的写法)【学习：子实现类】
 *            输出流：写入-->文件-->相对于程序-->程序写出
 *            OutputStream(抽象类：定义所有的写法)【学习：子实现类】
 *
 *           ②功能划分：
 *           低级流【节点流】：是建立在程序与数据源之间的“管道”
 *                          功能：负责搬运的数据流，输入流于输出流都有自己的低级流
 *                          特点：一个字节一个字节读或者写的方法
 *            FileOutputStream   低级流继承InputString---文件输出流：写
 *            FileInputString    低级流继承OutputStream--文件输入流：读
 *           高级流【处理流】：不能直接创建对象，不能独立存在
 *                        功能：专门处理低级流以及其他高级流的流
 *                        特点：搬运数据时，实现具体功能：效率提高流
 *
 *
 *---------------------总结：输出流和输入流，具备功能：低级流与高级流-----------------------
 * --------------------实际使用：明确使用具体流，每个流都有自己的功能-----------------------
 */

public class IOAPI {
    /**
     *                            文件输出流
     *           输入流        低级流
     * 标准流  方向       功能：     文件输出流：FileOutputString √
     *          输出流         高级流
     * 需求：写出一个文件fos.txt
     * FileOutputStream 构造器使用
     * new FileOutputStream("路径+文件全称")
     * newFileOutputStream("路径+文件全称",boolean append)
     * 写出文件的同时追加效果，第二个参数：true  追加
     *                              false 默认不追加
     * new FileOutputStream(File file)
     */
    @Test
    public void testFOS()  {
        // 低级流---文件输出流对象
           // RandomAccessFile raf=new RandomAccessFile("fos.txt","rw");
           FileOutputStream fos=null;
            //低级流---文件输出对象---从程序中写出“文件：数据”
        try {
            fos = new FileOutputStream("fos.txt",true);
            //需求：fos.txt 增加一行文本，每次运行实现追加效果
            fos.write("独一无二".getBytes());
            fos.flush();
            String say="独one无two";
            //字符串由数组构成---数组的功能getBytes()转换为字节数组
            //输出流---写功能：write(byte[] b) 写出字节数组
            fos.write(say.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
    }

/**
 * 文件输入流：读入操作
 * FileOutputStream 文件输入流
 * read() 返回一个读取一个字节
 * read(字节数组byte[] b)  返回一个指定字节数组的空间---效率高
 * 需求： 读入fos.txt文件内容
 *
 *
 */
  @Test
  public void testFIS()  {
      //创建文件输入流---读入：fos.txt
      byte[] data= new byte[0];
      int len= 0;
      try {
          FileInputStream fis=new FileInputStream("fos.txt");
          //读入效率高：创建字节数组-指定空间为：10KB
          data = new byte[1024*10];
          //读入操作：read(字节数组)    \      以10KB读入数据
          len = fis.read(data);
      } catch (IOException e) {
          e.printStackTrace();
      } finally {
      }
      //写出：文本---字符串---针对流操作，提供构造器
      //                   将文件按照“指定字节数组空间”写入程序中
      //                   从0开始写入程序，写入到-1结束
      //                   len:十进制转换为二进制，写入，不等于-1，一直写入
      //一次性将给定数据按照字节数组指定空间大小 ，写出成字符串
      String str=new String(data,0,len);
      System.out.println("打印Fos.txt文件："+str);


  }
    /**
     *
     */
     @Test
    public void testCV() throws IOException {
         //1.从“复制文件.mp4”      复制 操作---读入
         FileInputStream fis= null;
         FileOutputStream fos= null;
         try {
             fis = new FileInputStream("复制视频.mp4");
             //2.创建新文件“新文件.mp4” 粘贴 操作---写出
             fos = new FileOutputStream("新视频.mp4");
             //3.保存每次读取的数据【字节量--int】
             int len=-1;
             //4.一直从“复制文件.mp4"进行读入操作,不等于-1   一直读
             //   (fis.read())!=-1   ----   一个字节一个字节读
             while ((len = fis.read()) != -1) {  //true
                 //4.1同时 写出”新文件.mp4“
                 fos.write(len);
             }
         } catch (IOException e) {
             e.printStackTrace();
         } catch(Exception e){  //"大"异常   Exception
             e.printStackTrace();
         }finally {if(fos!=null)
             try {
                 fos.close();
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }


         //5.关闭流
        fis.close(); fos.close();

     }
    /**
     * 需求：利用标准流实现视频复制粘贴---效率低
     *                             效率高--->空间执行为：自定 100KB
     *【高级流】BufferedInputString  缓冲输入流--提升效率--缓冲区：字节数组【长度按照文件大小河里分配】
     *        BufferedInputString  缓冲输出流--提升效率--缓冲区：字节数组【长度按照文件大小河里分配】
     * 高级流使用方式：①处理低级流，套在低级流上
     *              写法：new 高级流
     *              ②
     *              ③高级流不能直接创建【不能独立存在】
     *
     */
    @Test
    public void testCVS() throws IOException {
        //1.创建低级流：读入”复制视频“
        FileInputStream fis=new FileInputStream("复制视频.mp4");
        //1.创建高级流：套在低级流上【自带缓冲区：字节数组】
        BufferedInputStream bis=new BufferedInputStream(fis);

        //2.创建低级流：写出”高效视频.mp4“
        FileOutputStream fos=new FileOutputStream("高效视频.mp4");
        //2.创建高级流：套在低级流上【自带缓冲区：字节数组】
        BufferedOutputStream bos=new BufferedOutputStream(fos);
        //3.保存数据
        int len=-1;
        //4.高级流--低级流方法一致---read() 读取内嵌缓冲区【字节数组】
        //一直从”复制视频.mp4“读取数据，不等于-1，一直读
        //(len=bis.read())!=-1
        long start=System.currentTimeMillis();  //系统时间毫秒数
        while((len=bis.read())!=-1){
          bos.write(len);
        }
        long end=System.currentTimeMillis();
        System.out.println("缓冲流【自带缓冲区】："+(end-start)+"毫秒数");
        //关闭流---高级流与低级流：都关--->高级流间接性关闭低级流-->关闭高级流
        bis.close(); //高级流--缓冲输入流
        bos.close(); //高级流--缓冲输出流

    }
    /**
     * 高级流----缓冲流【内嵌缓冲区】
     * BufferedOutputStream  缓冲输出流
     *
     * 需求：通过缓冲输出流实现从程序写出文件：bos.txt、写出内容
     *
     */
    @Test
    public void testBOS()  {
        //1.创建低级流-->bos.txt
        FileOutputStream fos= null;
        BufferedOutputStream bos= null;

        try {
            fos = new FileOutputStream("bos.txt");
            //2.创建高级流-->缓冲区：字节数组--合理【传输效率】
            bos = new BufferedOutputStream(fos);
            bos.write("独一无".getBytes());
            bos.flush();

            //3.写出文本内容
            String str="50  块钱设计的再好看也不如100块钱找人稀罕~~";
            //4.写出到bos.txt 文件中：字符串转成字节数组--写出
            bos.write(str.getBytes());
            //5.将缓冲区数据一次性写出   flush()
            // bos.flush();
            // A  B  泥豪   你认识我吗   干啥呢  ？？
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }catch(Exception e){  //"大"异常   Exception
            e.printStackTrace();
        }

        finally {
            if(bos!=null)
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //bos.close();  //关闭流---一定把缓冲区数据全部写出
    }
    /**
     * 标准IO---成对【低级流+高级流】结合异常---数据传输---成功【异常需要捕获】
     */
    @Test
    public void testBOSIO(){
        //1.置空流---提升所有流作用域：使用范围
        FileOutputStream fos=null;  //低级流：搬运数据
        BufferedOutputStream bos=null; //高级流：缓冲输出流
        //2.捕获流异常并且做出处理
        try {
            fos=new FileOutputStream("bos.txt"); //低级流
            bos=new BufferedOutputStream(fos);  //高级流：缓冲区：字节数组
            bos.write("独一无二".getBytes());
            bos.flush();
        }catch(FileNotFoundException e){   //IO流”小“异常
            e.printStackTrace();
        } catch (IOException e) {   //IO流”中“异常：小异常父类
            e.printStackTrace();
        }catch(Exception e){  //"大"异常   Exception
            e.printStackTrace();
        }
        finally {
            //3.关闭流---高级流--释放资源
            //判断：高级流不为null,关闭
            if(bos!=null)
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }

    }
}






